home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF CDF 'create' operations.
- *
- * Version 1.0, 10-Feb-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 10-Feb-92, J Love Original version (was part of `cdflib.c').
- *
- ******************************************************************************/
-
- #include "cdflib.h"
-
- /******************************************************************************
- * CDFcre.
- ******************************************************************************/
-
- CDFstatus CDFcre (ap, item, fnc)
- va_list *ap;
- long item;
- long *fnc;
- {
- CDFstatus Pstatus = CDF_OK;
- CDFstatus Tstatus;
-
- switch (item) {
- case CDF_: {
- CDFid *id;
- char *CDFname;
- long numDims;
- long *dimSizes;
- char cdfname[CDF_PATHNAME_LEN+1];
- char cdfnameX[CDF_PATHNAME_LEN+4+1]; /* +4+1 for .CDF and NUL-terminator */
- CDFid newid;
- long i, Nbytes;
- File *tmpfp;
- struct cdfSTRUCT *CDF;
- long eof; /* maintained until GDR created */
-
- CDFname = va_arg (*ap, char *);
- numDims = va_arg (*ap, long);
- dimSizes = va_arg (*ap, long *);
- id = va_arg (*ap, CDFid *);
-
- if (numDims < 0 || numDims > CDF_MAX_DIMS) return BAD_NUM_DIMS;
- for (i = 0; i < numDims; i++) if (dimSizes[i] < 1) return BAD_DIM_SIZE;
-
- if (strlen(CDFname) > CDF_PATHNAME_LEN) {
- strncpy (cdfname, CDFname, CDF_PATHNAME_LEN);
- cdfname[CDF_PATHNAME_LEN] = NUL;
- STATUSdisp (CDF_NAME_TRUNC, Pstatus);
- }
- else
- strcpy (cdfname, CDFname);
-
- #if defined(vms) /** remove trailing blanks if VMS **/
- for (i = strlen(cdfname) - 1; i >= 0; i--) {
- if (cdfname[i] == ' ')
- cdfname[i] = NUL;
- else
- break;
- }
- #endif
- if ( ! validCDFname(cdfname)) return BAD_CDF_NAME;
-
- /** find CDFid to use **/
-
- for (newid = 0; newid < CDF_MAX_CDFS; newid++)
- if (_CDFs[newid] == NULL) break;
-
- if (newid == CDF_MAX_CDFS) return TOO_MANY_CDFS;
-
- /* Check if the CDF already exists */
-
- ExpandPath (cdfname, cdfnameX);
- strcat (cdfnameX, ".cdf");
-
- if (IsReg(cdfnameX)) return CDF_EXISTS;
-
- #if defined(vms) | defined(__MSDOS__)
- tmpfp = OpenFile (cdfnameX,"w+b");
- #endif
- #if defined(unix)
- tmpfp = OpenFile (cdfnameX,"w+");
- #endif
- if (tmpfp == NULL) return CDF_CREATE_ERROR;
-
- _CDFs[newid] = (struct cdfSTRUCT *) malloc (sizeof(struct cdfSTRUCT));
- if (_CDFs[newid] == NULL) return BAD_MALLOC; /*CLEAN UP!*/
-
- CDF = _CDFs[newid];
-
- CDF->status = CDF_READ_WRITE;
- CDF->fp = tmpfp;
-
- strcpy (CDF->filename, cdfname);
- CDF->id = newid;
-
- eof = 0;
-
- /*** Set up magic number(s) ***/
-
- CDF->magic_number = V2_MAGIC_NUMBER;
- eof += sizeof(Int32);
- eof += sizeof(Int32); /* magic number written twice */
-
- /*** Set up CDR ***/
-
- CDF->CDRoffset = V2_CDR_OFFSET;
- CDF->CDR.RecordSize = CDR_BASE_SIZE + CDF_COPYRIGHT_LEN;
- CDF->CDR.RecordType = CDR_;
-
- /*** CDR.GDRoffset calculated below ***/
-
- CDF->CDR.Version = CDF_LIBRARY_VERSION;
- CDF->CDR.Release = CDF_LIBRARY_RELEASE;
- CDF->CDR.Increment = CDF_LIBRARY_INCREMENT;
- CDF->CDR.Encoding = _CDFhostEncoding;
-
- CDF->CDR.Flags = 0;
-
- setbit (CDF->CDR.Flags, CDF_MAJORITY_BIT); /* majority --> ROW_MAJOR */
- clrbit(CDF->CDR.Flags, CDF_FORMAT_BIT); /* format --> MULTI_FILE */
-
- CDF->CDR.rfuA = 0;
- CDF->CDR.rfuB = 0;
- CDF->CDR.rfuD = -1;
- CDF->CDR.rfuE = -1;
-
- strcpy (CDF->CDR.copyright, _CDF_CopyRight);
-
- eof = CDF->CDRoffset + CDF->CDR.RecordSize;
-
- /*** Set up GDR ***/
-
- CDF->GDRoffset = eof;
- CDF->CDR.GDRoffset = CDF->GDRoffset;
-
- /*** GDR.RecordSize calculated below ***/
-
- CDF->GDR.RecordType = GDR_;
- CDF->GDR.VDRhead = 0;
- CDF->GDR.garbage1 = 0; /* in V2.0 CDFs this field
- contained a random value */
- CDF->GDR.ADRhead = 0;
-
- /*** GDR.eof calculated below ***/
-
- CDF->GDR.NumVar = 0;
- CDF->GDR.NumAttr = 0;
- CDF->GDR.MaxRec = -1;
- CDF->GDR.NumDims = numDims;
-
- CDF->GDR.rfuA = 0;
- CDF->GDR.rfuB = 0;
- CDF->GDR.rfuC = 0;
- CDF->GDR.rfuD = -1;
- CDF->GDR.rfuE = -1;
-
- if (numDims > 0) {
- CDF->GDR.DimSizes = (Int32 *) malloc (numDims * sizeof(Int32));
- if (CDF->GDR.DimSizes == NULL) return BAD_MALLOC;
- for (i = 0; i < numDims; i++) CDF->GDR.DimSizes[i] = dimSizes[i];
- }
- else
- CDF->GDR.DimSizes = NULL;
-
- CDF->GDR.RecordSize = GDR_BASE_SIZE + CDF->GDR.NumDims*sizeof(Int32);
- CDF->GDR.eof = CDF->GDRoffset + CDF->GDR.RecordSize;
-
- CDF->recnum = 0;
- CDF->reccount = 1;
- CDF->recinterval = 1;
-
- if (numDims > 0) {
- Nbytes = numDims * sizeof(long);
-
- CDF->indices = (long *) malloc (Nbytes);
- if (CDF->indices == NULL) return BAD_MALLOC; /* CLEAN UP */
- CDF->counts = (long *) malloc (Nbytes);
- if (CDF->counts == NULL) return BAD_MALLOC; /* CLEAN UP */
- CDF->intervals = (long *) malloc (Nbytes);
- if (CDF->intervals == NULL) return BAD_MALLOC; /* CLEAN UP */
-
- for (i = 0; i < numDims; i++) {
- CDF->indices[i] = 0;
- CDF->counts[i] = dimSizes[i];
- CDF->intervals[i] = 1;
- }
- }
- else {
- CDF->indices = NULL;
- CDF->counts = NULL;
- CDF->intervals = NULL;
- }
-
- CDF->CURentryNum = RESERVED_ENTRYNUM;
-
- CDF->attrHead = NULL;
- CDF->attrTail = NULL;
-
- CDF->varHead = NULL;
- CDF->varTail = NULL;
- for (i = 0; i < CDF_MAX_VARS; i++) CDF->var[i] = NULL;
-
- CDF->CURattr = NULL;
- CDF->CURentry = NULL;
- CDF->CURvar = NULL;
-
- _CURcdf = CDF;
-
- *id = newid;
- break;
- }
- case VAR_: {
- long *varnum;
- long dataType;
- long numElements;
- long recVariance;
- long *dimVariances;
- char *varName;
- char truncname[CDF_VAR_NAME_LEN+1];
- char openname[CDF_PATHNAME_LEN+6+1]; /* +6+1 for .Vnnnn and
- NUL-terminator */
- long newvarnum;
- long i;
- File *fp;
- struct varSTRUCT *Var;
- struct varSTRUCT *ntlVar; /* next-to-last Var */
- long Nbytes;
-
- varName = va_arg (*ap, char *);
- dataType = va_arg (*ap, long);
- numElements = va_arg (*ap, long);
- recVariance = va_arg (*ap, long);
- dimVariances = va_arg (*ap, long *);
- varnum = va_arg (*ap, long *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if ( ! validDataType(dataType)) return BAD_DATA_TYPE;
- if (numElements < 1) return BAD_NUM_ELEMS;
-
- if (dataType != CDF_CHAR && dataType != CDF_UCHAR)
- if (numElements != 1) return BAD_NUM_ELEMS;
-
- if (strlen(varName) > CDF_VAR_NAME_LEN) {
- strncpy (truncname, varName, CDF_VAR_NAME_LEN);
- truncname[CDF_VAR_NAME_LEN] = NUL;
- STATUSdisp (VAR_NAME_TRUNC, Pstatus);
- }
- else
- strcpy (truncname, varName);
-
- if ( ! validVarName(truncname)) return BAD_VAR_NAME;
-
- Var = _CURcdf->varHead;
- while (Var != NULL) {
- if (strcmpITB(Var->VDR.Name,truncname) == 0) return VAR_EXISTS;
- Var = Var->varNext;
- }
-
- if (_CURcdf->GDR.NumVar >= CDF_MAX_VARS) return TOO_MANY_VARS;
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- /* Look for empty variable number slot */
-
- for (newvarnum = 0; newvarnum < CDF_MAX_VARS; newvarnum++)
- if (_CURcdf->var[newvarnum] == NULL) break;
-
- if (bitclr(_CURcdf->CDR.Flags, CDF_FORMAT_BIT)) {
- sprintf (openname, "%s.v%d", _CURcdf->filename, newvarnum);
- #if defined(vms) | defined(__MSDOS__)
- fp = OpenFile (openname,"w+b");
- #endif
- #if defined(unix)
- fp = OpenFile (openname,"w+");
- #endif
- if (fp == NULL) return VAR_CREATE_ERROR;
- Close (fp);
- }
-
- Var = (struct varSTRUCT *) malloc (sizeof(struct varSTRUCT));
- if (Var == NULL) return BAD_MALLOC; /* CLEAN UP! */
-
- if (_CURcdf->varHead == NULL) { /* first variable */
- ntlVar = (struct varSTRUCT *) NULL;
- _CURcdf->varHead = Var;
- _CURcdf->varTail = Var;
- }
- else {
- ntlVar = _CURcdf->varTail;
- _CURcdf->varTail->varNext = Var;
- _CURcdf->varTail = Var;
- }
-
- Var->varNext = (struct varSTRUCT *) NULL;
-
- if (bitclr(_CURcdf->CDR.Flags,CDF_FORMAT_BIT)) {
- Var->fp = fp; /* variable data in .Vnn */
- Var->status = VAR_CLOSED;
- }
- else {
- Var->fp = _CURcdf->fp; /* variable data in .CDF */
- Var->status = NO_VAR_FILE;
- }
-
- /*** Set up VDR ***/
-
- Var->VDRoffset = _CURcdf->GDR.eof;
-
- Var->VDR.RecordSize = VDR_BASE_SIZE +
- CDF_VAR_NAME_LEN +
- CDF_VAR_FILE_NAME_LEN +
- _CURcdf->GDR.NumDims*sizeof(Int32);
- Var->VDR.RecordType = VDR_;
- Var->VDR.VDRnext = 0;
- Var->VDR.DataType = dataType;
- Var->VDR.MaxRec = -1;
- Var->VDR.VXRhead = 0;
- Var->VDR.VXRtail = 0;
-
- Var->VDR.Flags = 0;
-
- if (recVariance)
- setbit(Var->VDR.Flags,VAR_RECVARY_BIT);
- else
- clrbit(Var->VDR.Flags,VAR_RECVARY_BIT);
-
- clrbit(Var->VDR.Flags,VAR_FILLVALUE_BIT);
-
- Var->VDR.rfuA = 0;
- Var->VDR.rfuB = 0;
- Var->VDR.rfuC = -1;
-
- Var->VDR.REFvarNum = -1;
- Var->VDR.REFfilename[0] = '\0';
- Var->VDR.NumElem = numElements;
- Var->VDR.Num = newvarnum;
-
- Var->VDR.rfuD = -1;
- Var->VDR.NextendRecs = 0;
-
- strcpy (Var->VDR.Name, truncname);
-
- if (_CURcdf->GDR.NumDims > 0) {
- Var->VDR.DimVarys = (Int32 *) malloc (_CURcdf->GDR.NumDims *
- sizeof(Int32));
- if (Var->VDR.DimVarys == NULL) return BAD_MALLOC; /* CLEAN UP! */
-
- for (i = 0; i < _CURcdf->GDR.NumDims; i++)
- if (dimVariances[i])
- Var->VDR.DimVarys[i] = VARY;
- else
- Var->VDR.DimVarys[i] = NOVARY;
- }
- else
- Var->VDR.DimVarys = NULL;
-
- Var->VDR.FillValue = NULL;
-
- _CURcdf->GDR.eof += Var->VDR.RecordSize;
-
- /*** point next-to-last VDR (or GDR) to this VDR ***/
-
- if (ntlVar == NULL)
- _CURcdf->GDR.VDRhead = Var->VDRoffset;
- else
- ntlVar->VDR.VDRnext = Var->VDRoffset;
-
- /*** allocate and set up variable control data ***/
-
- if (_CURcdf->GDR.NumDims > 0) {
- Nbytes = _CURcdf->GDR.NumDims * sizeof(long);
- Var->products = (long *) malloc (Nbytes);
- if (Var->products == NULL) return BAD_MALLOC; /* CLEAN UP */
- Var->hypProducts = (long *) malloc (Nbytes);
- if (Var->hypProducts == NULL) return BAD_MALLOC; /* CLEAN UP */
- Var->hypIndices = (long *) malloc (Nbytes);
- if (Var->hypIndices == NULL) return BAD_MALLOC; /* CLEAN UP */
- Var->hypTops = (long *) malloc (Nbytes);
- if (Var->hypTops == NULL) return BAD_MALLOC; /* CLEAN UP */
- }
- else {
- Var->products = NULL;
- Var->hypProducts = NULL;
- Var->hypIndices = NULL;
- Var->hypTops = NULL;
- }
-
- Var->seqValueOffset = 0;
-
- calcVarParms (_CURcdf, Var);
-
- Var->vixHead = (struct vixSTRUCT *) NULL;
- Var->vixTail = (struct vixSTRUCT *) NULL;
-
- /*** tally another variable ***/
-
- _CURcdf->GDR.NumVar++;
-
- _CURcdf->var[newvarnum] = Var;
- _CURcdf->CURvar = Var;
-
- *varnum = newvarnum;
- break;
- }
- case ATTR_: {
- long *attrnum;
- char *attrname;
- long scope;
- struct attrSTRUCT *Attr;
- struct attrSTRUCT *ntlAttr; /* next-to-last Attr */
- char truncname[CDF_ATTR_NAME_LEN+1];
-
- attrname = va_arg (*ap, char *);
- scope = va_arg (*ap, long);
- attrnum = va_arg (*ap, long *);
-
- if (_CURcdf == NULL) return NO_CDF_SELECTED;
- if (_CURcdf->CDR.Version == 1) return ILLEGAL_ON_V1_CDF;
- if ( ! validAttrScope(scope)) return BAD_SCOPE;
-
- if (strlen(attrname) > CDF_ATTR_NAME_LEN) {
- strncpy (truncname, attrname, CDF_ATTR_NAME_LEN);
- truncname[CDF_ATTR_NAME_LEN] = NUL;
- STATUSdisp (ATTR_NAME_TRUNC, Pstatus);
- }
- else
- strcpy (truncname, attrname);
-
- if ( ! validAttrName(truncname)) return BAD_ATTR_NAME;
-
- Attr = _CURcdf->attrHead;
- while (Attr != NULL) {
- if (strcmpITB(truncname,Attr->ADR.Name) == 0) return ATTR_EXISTS;
- Attr = Attr->attrNext;
- }
-
- if (_CURcdf->status == CDF_READ_ONLY) {
- Tstatus = ReopenCDFforWrite (_CURcdf);
- STATUSdisp (Tstatus, Pstatus);
- }
-
- Attr = (struct attrSTRUCT *) malloc (sizeof(struct attrSTRUCT));
- if (Attr == NULL) return BAD_MALLOC;
-
- if (_CURcdf->attrHead == NULL) { /* first attribute */
- ntlAttr = (struct attrSTRUCT *) NULL;
- _CURcdf->attrHead = Attr;
- _CURcdf->attrTail = Attr;
- }
- else {
- ntlAttr = _CURcdf->attrTail;
- _CURcdf->attrTail->attrNext = Attr;
- _CURcdf->attrTail = Attr;
- }
-
- Attr->attrNext = (struct attrSTRUCT *) NULL;
-
- /*** Set up ADR ***/
-
- Attr->ADRoffset = _CURcdf->GDR.eof;
-
- Attr->ADR.RecordSize = ADR_BASE_SIZE + CDF_ATTR_NAME_LEN;
- Attr->ADR.RecordType = ADR_;
- Attr->ADR.ADRnext = 0;
- Attr->ADR.AEDRhead = 0;
- Attr->ADR.Scope = scope;
- Attr->ADR.Num = _CURcdf->GDR.NumAttr;
- Attr->ADR.NumEntries = 0;
- Attr->ADR.MaxEntry = -1;
-
- Attr->ADR.rfuA = 0;
- Attr->ADR.rfuB = 0;
- Attr->ADR.rfuC = 0;
- Attr->ADR.rfuD = -1;
- Attr->ADR.rfuE = -1;
-
- strcpy (Attr->ADR.Name, truncname);
-
- _CURcdf->GDR.eof += Attr->ADR.RecordSize;
-
- /*** point next-to-last ADR (or GDR) to this ADR ***/
-
- if (ntlAttr == NULL)
- _CURcdf->GDR.ADRhead = Attr->ADRoffset;
- else
- ntlAttr->ADR.ADRnext = Attr->ADRoffset;
-
- /*** set up entry list ***/
-
- Attr->entryHead = NULL;
- Attr->entryTail = NULL;
-
- _CURcdf->GDR.NumAttr++;
-
- _CURcdf->CURattr = Attr;
- _CURcdf->CURentry = NULL; /* no entries in attr. yet */
-
- *attrnum = Attr->ADR.Num;
- break;
- }
- default: {
- *fnc = item;
- break;
- }
- }
- return Pstatus;
- }
-